<?php
/**
 * Created by Zhy
 * User: Zhy
 * Date: 2021/10/9
 * Time: 9:40
 */

namespace app\api\controller;


use think\Db;

class Groupchat extends Base
{
    public $user_id;
    public $create_time;
    public $page;
    public $appKey; // 融云key
    public $appSecret; // 融云秘钥
    
    /**
     * 异地登录验证
     * @return string
     */
    public function __construct()
    {
        $this->user_id = input('user_id');
        $this->page = input('page') ? input('page') : 1;
        $this->create_time = date('Y-m-d H:i:s');
        $time = input('time');
        $value = input('value');
        $reqKey = input('reqKey');
        $auth = $this->checkAll($this->user_id, $time, $value, $reqKey);
        if($auth == 112){
            echo json_encode(['status' => 301, 'msg' => $this->otherLogin]);
            exit;
        }elseif($auth == 110){
            echo json_encode(['status' => 302, 'msg' => $this->frost]);
            exit;
        }elseif($auth == 2111){
            echo json_encode(['status' => 303, 'msg' => $this->del]);
            exit;
        }
    }
    
    /**
     * 可聊天用户列表
     * @return \think\response\Json
     */
    public function myFriends(){
        $user = Db::table('up_u_user')->where('user_id', $this->user_id)->field('user_invite')->find();
        $down = Db::table('up_u_user')
            ->where('user_invite_other', $user['user_invite'])
            ->where('user_status', 1)
            ->field('user_id, user_username, user_invite, user_image')
            ->select();
        
        if($down){
            $down_down = [];
            foreach($down as $ke => $vo){
                $_down = Db::table('up_u_user')
                    ->where('user_invite_other', $vo['user_invite'])
                    ->where('user_status', 1)
                    ->field('user_id, user_username, user_image')
                    ->select();
                $down_down = array_merge($down_down, $_down);
            }
            $chatUserList = array_merge($down, $down_down);
            
            foreach($chatUserList as $kk => $vv){
                // 字母排序
                $chatUserList[$kk]['letter'] = $this->Getzimu($chatUserList[$kk]['user_username']);
            }
            $new_names = array_column($chatUserList, 'letter');
            array_multisort($new_names, SORT_ASC, $chatUserList);
            $start = '';
            $res = array();
            foreach ($chatUserList as $k => $v) {
                if ($v['letter'] != $start) {
                    $start = $v['letter'];
                }
                $res[$start][] = $v;
            }
            $jing = array();
            if(isset($res['#'])){
                $jing['#'] = $res['#'];
                unset($res['#']);
            }
            $chatUserList = array_merge($res,$jing);
        }else{
            $chatUserList = [];
        }
        return json(['status' => 200, 'msg' => $chatUserList]);
    }
    
    /**
     * 创建群聊
     * @return \think\response\Json
     * userId      群聊用户
     * groupName   群聊名称
     */
    public function createGroupChat(){
        $userId = input('userId'); // 需要加入群聊的用户ID
        $groupName = input('gorupName'); // 群聊名称
        $userArr = explode(',', $userId);
        
        if(!$userArr) return json(['status' => 0, 'msg' => '请添加群聊人员']);
        if(count($userArr) < 3) return json(['status' => 0, 'msg' => '群聊人数需大于两人']);
        $groupId = $this->uuid();
        
        // 群聊表
        $insert = [
            'gc_id' => $groupId,
            'gc_name' => $groupName,
            'gc_user_id' => $this->user_id,
            'gc_time' => $this->create_time
        ];
        // 群聊用户
        $insert_user = [];
        foreach($userArr as $ku => $vu){
            $user_name = Db::table('up_u_user')->where('user_id', $vu)->value('user_username');
            $insert_user[$ku] = [
                'cu_user_id' => $vu,
                'cu_gc_id' => $groupId,
                'cu_user_name' => $user_name,
            ];
        }
        
        $user_str = $this->getUserStr($userArr);
        $body = $user_str . "groupId=$groupId&groupName=$groupName";
        Db::startTrans();
        try{
            // 插入群聊表
            Db::table('up_user_group_chat')->insert($insert);
            
            // 插入群聊用户
            Db::table('up_user_group_chat_users')->insertAll($insert_user);
    
            $result = $this->sendHttp($body, 'create');
            if($result['code'] == 200){
                $msg = $groupId;
                $code = 200;
            }else{
                Db::table('up_user_group_chat')->delete($groupId);
                Db::table('up_user_group_chat_users')->where('cu_gc_id', $groupId)->delete();
                $code = 0;
                $msg = $result['errorMessage'];
            }
            Db::commit();
            return json(['status' => $code, 'msg' => $msg]);
        }catch(\Exception $e){
            Db::rollback();
            return json(['status' => 0, 'msg' => $e->getMessage()]);
        }
    }
    
    /**
     * 加入群聊
     * @return \think\response\Json
     * userId      需要添加的用户ID，逗号隔开
     * groupId     群ID
     */
    public function joinGroupChat(){
        $userId = input('userId'); // 需要添加的用户ID，逗号隔开
        $groupId = input('groupId');
        $userArr = explode(',', $userId);
    
        if(!$userArr) return json(['status' => 0, 'msg' => '请选择需要添加的人员']);
        
        $group = Db::table('up_user_group_chat')
            ->where('gc_id', $groupId)
            ->field('gc_status, gc_name')
            ->find();
        if($group['gc_status'] == 2) return json(['status' => 0, 'msg' => '此群已解散']);
        
        $is_in = 0;
        $username = '';
        foreach($userArr as $k => $v){
            $has_in = Db::table('up_user_group_chat_users')
                ->join('up_u_user', 'user_id = cu_user_id', 'LEFT')
                ->where(['cu_user_id' => $v, 'cu_gc_id' => $groupId])
                ->field('user_username')
                ->find();
            if($has_in){
                $username = $has_in['user_username'];
                $is_in = 1;
                break;
            }
        }
        if($is_in == 1) return json(['status' => 0, 'msg' => $username . '已在该群聊中']);
    
        $insert_user = [];
        foreach($userArr as $ku => $vu){
            $user_name = Db::table('up_u_user')->where('user_id', $vu)->value('user_username');
            $insert_user[$ku] = [
                'cu_user_id' => $vu,
                'cu_gc_id' => $groupId,
                'cu_user_name' => $user_name
            ];
        }
    
        $res = Db::table('up_user_group_chat_users')->insertAll($insert_user);
        if($res){
            $user_str = $this->getUserStr($userArr);
            $body = "{$user_str}groupId=$groupId&groupName={$group['gc_name']}";
            $result = $this->sendHttp($body, 'join');
            if($result['code'] == 200){
                $status = 200;
                $msg = '添加成功';
            }else{
                Db::table('up_user_group_chat_users')
                    ->where(['cu_user_id' => ['IN', $userId], 'cu_gc_id' => $groupId])
                    ->delete();
                $status = 0;
                $msg = $result['errorMessage'];
            }
        }else{
            $status = 0;
            $msg = '添加失败';
        }
        return json(['status' => $status, 'msg' => $msg]);
    }
    
    /**
     * 退出并删除
     * @return \think\response\Json
     * groupId      群ID
     */
    public function quitGroupChat(){
        $groupId = input('groupId');
        $group = Db::table('up_user_group_chat')->where('gc_id', $groupId)
            ->field('gc_user_id')->find();
        $body = "userId=$this->user_id&groupId=$groupId";
        if($group['gc_user_id'] == $this->user_id){ // 如果是群主，则解散群
            $res = Db::table('up_user_group_chat')->where('gc_id', $groupId)->setField('gc_status', 2);
            if($res){
                $result = $this->sendHttp($body, 'dismiss');
                if($result['code'] == 200){
                    $status = 200;
                    $msg = '操作成功';
                }else{
                    Db::table('up_user_group_chat')->where('gc_id', $groupId)->setField('gc_status', 1);
                    $status = 0;
                    $msg = $result['errorMessage'];
                }
            }else{
                $status = 0;
                $msg = '操作失败';
            }
        }else{
            $user = Db::table('up_user_group_chat_users')
                ->where(['cu_user_id' => $this->user_id, 'cu_gc_id' => $groupId])
                ->field('cu_id, cu_user_name, cu_top, cu_no, cu_user_id, cu_gc_id')
                ->find();
            $res = Db::table('up_user_group_chat_users')
                ->where('cu_id', $user['cu_id'])
                ->delete();
            if($res){
                $result = $this->sendHttp($body, 'quit');
                if($result['code'] == 200){
                    $status = 200;
                    $msg = '操作成功';
                }else{
                    Db::table('up_user_group_chat_users')->insert($user);
                    $status = 0;
                    $msg = $result['errorMessage'];
                }
            }else{
                $status = 0;
                $msg = '操作失败';
            }
        }
        return json(['status' => $status, 'msg' => $msg]);
    }
    
    /**
     * 移除
     * @return \think\response\Json
     * groupId       群ID
     * userId        需要移除的用户ID，逗号隔开
     */
    public function quitUsers(){
        $groupId = input('groupId');
        $userId = input('userId');
        $userArr = explode(',', $userId);
    
        if(!$userArr) return json(['status' => 0, 'msg' => '请选择需要删除的人员']);
        
        $group = Db::table('up_user_group_chat')->where('gc_id', $groupId)->field('gc_user_id')->find();
        if($group['gc_user_id'] != $this->user_id) return json(['status' => 0, 'msg' => '您不是群主，不可以操作']);
        
        $users = Db::table('up_user_group_chat_users')
            ->where(['cu_gc_id' => $groupId, 'cu_user_id' => ['IN', $userId]])
            ->field('cu_id, cu_user_id, cu_user_name, cu_top, cu_no, cu_gc_id')
            ->select();
        
        $res = Db::table('up_user_group_chat_users')
            ->where(['cu_gc_id' => $groupId, 'cu_user_id' => ['IN', $userId]])
            ->delete();
        if($res){
            $user_str = $this->getUserStr($userArr);
            $body = "{$user_str}groupId=$groupId";
            $result = $this->sendHttp($body, 'quit');
            if($result['code'] == 200){
                $status = 200;
                $msg = '操作成功';
            }else{
                Db::table('up_user_group_chat_users')->insertAll($users);
                $status = 0;
                $msg = $result['errorMessage'];
            }
        }else{
            $status = 0;
            $msg = '操作失败';
        }
        return json(['status' => $status, 'msg' => $msg]);
    }
    
    /**
     * 更新群信息
     * @return \think\response\Json
     * groupName     群名称
     * groupId       群ID
     */
    public function updateGroup(){
        $group_name = input('groupName');
        $groupId = input('groupId');
        
        $group = Db::table('up_user_group_chat')->where('gc_id', $groupId)->field('gc_name, gc_user_id')->find();
        if($group['gc_user_id'] != $this->user_id) return json(['status' => 0, 'msg' => '您不是群主，不可以操作']);
        
        $res = Db::table('up_user_group_chat')->update(['gc_id' => $groupId, 'gc_name' => $group_name]);
        if($res){
            $body = "groupId=$groupId&groupName=$group_name";
            $result = $this->sendHttp($body, 'refresh');
            if($result['code'] == 200){
                $status = 200;
                $msg = '操作成功';
            }else{
                Db::table('up_user_group_chat')->update(['gc_id' => $groupId, 'gc_name' => $group['gc_name']]);
                $status = 0;
                $msg = $result['errorMessage'];
            }
        }else{
            $status = 0;
            $msg = '操作失败';
        }
        return json(['status' => $status, 'msg' => $msg]);
    }
    
    /**
     * 设置置顶&免打扰
     * @return \think\response\Json
     * groupId       群ID
     * set_number    设置状态值    1 开启   2 关闭
     * set_type      设置类型      1 置顶   2 免打扰
     */
    public function setUserGroup(){
        $groupId = input('groupId');
        $set_number = input('set_number'); // 1 开启   2 关闭
        $set_type = input('set_type'); // 1 置顶   2 免打扰
        
        if($set_type == 1){
            $field = 'cu_top';
        }else{
            $field = 'cu_no';
        }
        $res = Db::table('up_user_group_chat_users')
            ->where(['cu_user_id' => $this->user_id, 'cu_gc_id' => $groupId])
            ->update([$field => $set_number]);
        if($res){
            return json(['status' => 200, 'msg' => '操作成功']);
        }else{
            return json(['status' => 0, 'msg' => '操作失败']);
        }
    }
    
    /**
     * 我的群聊
     * @return \think\response\Json
     * groupIds    我的群聊ID，逗号隔开
     */
    public function myGroupChat(){
        $groupIds = input('groupIds');
        if($groupIds){
            $group = Db::table('up_user_group_chat')
                ->where('gc_id', 'IN', $groupIds)
                ->field('gc_id, gc_name')
                ->select();
            foreach($group as $k => $v){
                $num = Db::table('up_user_group_chat_users')->where('cu_gc_id', $v['gc_id'])->count();
                $group[$k]['num'] = $num;
            }
            return json(['status' => 200, 'msg' => $group]);
        }else{
            return json(['status' => 200, 'msg' => []]);
        }
    }
    
    /**
     * 群成员信息
     * @return \think\response\Json
     * groupId      群ID
     */
    public function groupUserInfo(){
        $groupId = input('groupId');
        $data = Db::table('up_user_group_chat_users')
            ->join('up_u_user', 'user_id = cu_user_id', 'LEFT')
            ->where('cu_gc_id', $groupId)
            ->field('user_id, cu_user_name, user_image')
            ->select();
        return json(['status' => 200, 'msg' => $data]);
    }
    
    /**
     * 群基本信息
     * @return \think\response\Json
     * groupId       群ID
     */
    public function groupBaseInfo(){
        $groupId = input('groupId');
        // 群信息
        $group = Db::table('up_user_group_chat')
            ->where('gc_id', $groupId)
            ->field('gc_name, gc_id, gc_user_id')
            ->find();
        $user_num = Db::table('up_user_group_chat_users')
            ->where('cu_gc_id', $groupId)->count();
        $group['user_num'] = $user_num;
        // 我在群里的信息
        $user = Db::table('up_user_group_chat_users')
            ->where(['cu_user_id' => $this->user_id, 'cu_gc_id' => $groupId])
            ->field('cu_user_name, cu_top, cu_no')
            ->find();
        return json(['status' => 200, 'msg' => $group, 'user' => $user]);
    }
    
    /**
     * 查询群是否解散&我是否还在群里
     * @return \think\response\Json
     * groupId      群ID
     */
    public function haveGroup(){
        $groupId = input('groupId');
        $group = Db::table('up_user_group_chat')
            ->where('gc_id', $groupId)
            ->field('gc_status')
            ->find();
        $status = 0; // 群解散了或者我不在群里了
        $has_in = Db::table('up_user_group_chat_users')->where(['cu_user_id' => $this->user_id, 'cu_gc_id' => $groupId])->find();
        if($group['gc_status'] == 1 && $has_in) $status = 1;
        
        return json(['status' => 200, 'msg' => $status]);
    }
    
    /**
     * 参加视频聊天用户信息
     * @return \think\response\Json
     * user_ids     用户ID，逗号隔开
     */
    public function chatUserInfo(){
        $user_ids = input('user_ids');
        $user = Db::table('up_u_user')
            ->where('user_id', 'IN', $user_ids)
            ->field('user_id, user_username, user_image')
            ->select();
        return json(['status' => 200, 'msg' => $user]);
    }
    
    /**
     * 保存聊天记录
     * @return \think\response\Json
     * chat_content       消息内容
     * chat_type          消息内容    1 文字   2 图片   3 视频   4 音频
     * group_id           群ID
     */
    public function chatRecord(){
        $chat_content = input('chat_content');
        $chat_type = input('chat_type'); // 1 文字   2 图片   3 视频   4 音频
        $group_id = input('group_id');
        $send_user_phone = Db::table('up_u_user')->where('user_id', $this->user_id)->value('user_phone');
        
        Db::startTrans();
        try{
            // 更新最后聊天时间
            Db::table('up_user_group_chat')->where('gc_id', $group_id)->update(['gc_last_time' => $this->create_time]);
            
            // 群聊明细
            $insert = [
                'chat_gc_id' => $group_id,
                'chat_send_user_id' => $this->user_id,
                'chat_send_phone' => $send_user_phone,
//            'chat_content' => $chat_content,
                'chat_type' => $chat_type,
                'chat_time' => $this->create_time
            ];
            if($chat_type == 4){ // 音频需要转码
                $arr = explode('/', $chat_content);
                $key = end($arr);
                $this->audioZhuanma($key);
                $audio_url = config('qiniu.domain') . 'audio_' . $key;
                $insert['chat_content'] = $audio_url;
            }else{
                $insert['chat_content'] = $chat_content;
            }
            Db::table('up_user_group_chat_info')->insert($insert);
            
            Db::commit();
            return json(['status' => 200, 'msg' => true]);
        }catch(\Exception $e){
            return json(['status' => 0, 'msg' => $e->getMessage()]);
        }
    }
    
    //*****************************************  公共函数
    /**
     * 发送请求
     * @param $body   请求内容
     * @param $url    请求地址
     * @return mixed
     */
    private function sendHttp($body, $desc){
        $this->appKey = config('rong.appKey');
        $this->appSecret = config('rong.appSecret');
        switch($desc){
            case 'create': // 创建
                $url = 'http://api2-cn.ronghub.com/group/create.json';
                break;
            case 'dismiss': // 解散
                $url = 'http://api2-cn.ronghub.com/group/dismiss.json';
                break;
            case 'join': // 加入
                $url = 'http://api2-cn.ronghub.com/group/join.json';
                break;
            case 'quit': // 退出
                $url = 'http://api2-cn.ronghub.com/group/quit.json';
                break;
            case 'query': // 群组成员查询
                $url = 'http://api2-cn.ronghub.com/group/query.json';
                break;
            case 'refresh': // 刷新群组信息，群组名称变更时调用
                $url = 'http://api2-cn.ronghub.com/group/refresh.json';
                break;
        }
        $timestamp = time()*1000; // 时间戳（毫秒）
        $nonce = rand(); // 随机数
        $signature = sha1($this->appSecret.$nonce.$timestamp); // 签名
        $header = array(
            'App-Key:' . $this->appKey,
            'Nonce:' . $nonce,
            'Timestamp:' . $timestamp,
            'Signature:' . $signature,
            'Content-Type: application/x-www-form-urlencoded'
        );
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
//    curl_setopt($ch, CURLOPT_SSL_VERI/FYPEER, false);
//    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $result = curl_exec($ch);
        curl_close($ch);
        $res = json_decode($result, true);
        return $res;
    }
    
    /**
     * 获取uuid
     * @param string $prefix
     * @return string
     */
    private function uuid($prefix = '')
    {
        $chars = md5(uniqid(mt_rand(), true));
        $uuid  = substr($chars,0,8);
        $uuid .= substr($chars,8,4);
        $uuid .= substr($chars,12,4);
        $uuid .= substr($chars,16,4);
        $uuid .= substr($chars,20,12);
        return $prefix . $uuid;
    }
    
    /**
     * 组装userId请求参数
     * @param $userArr    用户ID数组
     * @return string
     */
    private function getUserStr($userArr){
        $user_str = '';
        foreach($userArr as $v){
            $user_str .= 'userId=' . $v . '&';
        }
        return $user_str;
    }
    
    /**
     * 首字母
     * @param $str
     * @return string
     */
    public function Getzimu($str)
    {
        if(empty($str)){
            return '#';
        }
        $fchar = mb_substr($str, 0, 1, 'utf-8');
        // 判断表情    表情长度为4位
        if(strlen($fchar) >= 4 ){
            return '#';
        }
//        print_r(ord('z'));die;
//        $fchar=ord($str{0});
        if(ord($fchar) >= ord('A') && ord($fchar) <= ord('z')){
            return strtoupper($fchar);
        }
        $s1 = iconv('UTF-8', 'gb2312', $str);
        $s2 = iconv('gb2312', 'UTF-8', $s1);
        $s = $s2 == $str ? $s1 : $str;
        $asc = ord($s{0})*256+ord($s{1})-65536;
        if($asc >= -20319 && $asc <= -20284) return 'A';
        if($asc >= -20283 && $asc <= -19776) return 'B';
        if($asc >= -19775 && $asc <= -19219) return 'C';
        if($asc >= -19218 && $asc <= -18711) return 'D';
        if($asc >= -18710 && $asc <= -18527) return 'E';
        if($asc >= -18526 && $asc <= -18240) return 'F';
        if($asc >= -18239 && $asc <= -17923) return 'G';
        if($asc >= -17922 && $asc <= -17418) return 'H';
        if($asc >= -17417 && $asc <= -16475) return 'J';
        if($asc >= -16474 && $asc <= -16213) return 'K';
        if($asc >= -16212 && $asc <= -15641) return 'L';
        if($asc >= -15640 && $asc <= -15166) return 'M';
        if($asc >= -15165 && $asc <= -14923) return 'N';
        if($asc >= -14922 && $asc <= -14915) return 'O';
        if($asc >= -14914 && $asc <= -14631) return 'P';
        if($asc >= -14630 && $asc <= -14150) return 'Q';
        if($asc >= -14149 && $asc <= -14091) return 'R';
        if($asc >= -14090 && $asc <= -13319) return 'S';
        if($asc >= -13318 && $asc <= -12839) return 'T';
        if($asc >= -12838 && $asc <= -12557) return 'W';
        if($asc >= -12556 && $asc <= -11848) return 'X';
        if($asc >= -11847 && $asc <= -11056) return 'Y';
        if($asc >= -11055 && $asc <= -10247) return 'Z';
        return "#";
    }
}